package com.ncdnapp.core.filter;

import com.ncdnapp.core.annotations.Args;
import com.ncdnapp.core.annotations.WebLog;
import com.ncdnapp.util.JsonUtil;
import lombok.extern.slf4j.Slf4j;
import org.noear.solon.Utils;
import org.noear.solon.annotation.Component;
import org.noear.solon.core.handle.Action;
import org.noear.solon.core.handle.Context;
import org.noear.solon.core.handle.Handler;
import org.noear.solon.core.route.RouterInterceptor;
import org.noear.solon.core.route.RouterInterceptorChain;
import org.noear.solon.core.wrap.MethodWrap;

import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

/**
 * 统一日志输出
 */
@Component(index = 10)
@Slf4j
public class LogPrintInterceptor implements RouterInterceptor {
    @Override
    public void doIntercept(Context ctx, Handler mainHandler, RouterInterceptorChain chain) throws Throwable {
        Long time = System.currentTimeMillis();
        log.info("------------------------请求日志输出START------------------------");
        log.info("请求地址:{}", ctx.path());
        log.info("请求客户端IP:{}", ctx.realIp());
        log.info("请求token:{}", ctx.header("token"));
        Action action = ctx.action();
        WebLog webLog = null;
        if (action != null) {
            MethodWrap method = ctx.action().method();
            webLog = method.getAnnotation(WebLog.class);
            if (webLog != null) {
                Args args = webLog.args();
                if (args == null || args.print()) {
                    Map<String, Object> paramMap = new HashMap<>();
                    Collection<String> paramNameList = ctx.paramNames();
                    if (!Utils.isEmpty(paramNameList)) {
                        paramNameList.forEach(name -> paramMap.put(name, ctx.param(name)));
                    }

                    if (args == null || args.filterNames().length == 0) {
                        log.info("请求参数:{}", JsonUtil.toJsonString(paramMap));
                    } else {
                        String[] filteredNameArr = args.filterNames();
                        if (!Utils.isEmpty(filteredNameArr) && !Utils.isEmpty(paramMap)) {
                            Arrays.stream(filteredNameArr).forEach(paramMap::remove);
                        }
                        log.info("请求参数:{}", JsonUtil.toJsonString(paramMap));
                    }
                }
            }
        }

        Throwable throwable = null;
        try {
            chain.doIntercept(ctx, mainHandler);
        } catch (Throwable e) {
            throwable = e;
            throw e;
        } finally {
            time = System.currentTimeMillis() - time;
            if (webLog != null && webLog.response()) {
                log.info("请求执行结果:{}", JsonUtil.toJsonString(ctx.result));
            }
            if (throwable != null) {
                log.error("请求异常信息:", throwable);
            }
            log.info("请求执行耗时:{} 毫秒", time);
            log.info("------------------------请求日志输出END------------------------");
        }
    }
}
